/*****************************************************************************************
   
   Copyright (c) Microsoft Corporation. All rights reserved.

   Use of this code sample is subject to the terms of the Microsoft
   Public License, a copy of which should always be distributed with
   this file.  You can also access a copy of this license agreement at:
   http://www.microsoft.com/opensource/licenses.mspx#Ms-PL

 ****************************************************************************************/
using System;

namespace Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary
{
    public class Binding : Microsoft.CSA.FeedSync.FeedSyncLibrary.IFeedSyncItem
    {
        #region private variables

        private string m_Title;
        private string m_Description;
        private string m_ID;
        private string m_Name;
        private string m_NamespacePrefix;
        private string m_FeedSyncNamespacePrefix;

        private bool m_DefaultTitleDescription;

        private System.Collections.Generic.List<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field> m_FieldList = new System.Collections.Generic.List<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field>();
        private System.Collections.Generic.SortedList<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field> m_RequiredFieldSortedList = new System.Collections.Generic.SortedList<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field>();
        private System.Collections.Generic.SortedList<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace> m_NamespaceSortedList = new System.Collections.Generic.SortedList<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace>();
        private System.Collections.Generic.SortedList<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList> m_PickListSortedList = new System.Collections.Generic.SortedList<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList>();

        private System.Xml.XmlElement m_XmlElement;
        private System.Xml.XmlNamespaceManager m_XmlNamespaceManager;

        private Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.BindingCollection m_BindingCollection;

        private Microsoft.CSA.FeedSync.FeedSyncLibrary.Sync m_Sync;

        #endregion

        public Binding()
        {
        }

        public Binding(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.BindingCollection i_BindingCollection, string i_ID, string i_Name, bool i_CreateDefaultTitleDescription)
            : this(i_BindingCollection, i_ID, i_Name, System.String.Empty, System.String.Empty, i_CreateDefaultTitleDescription, System.String.Empty)
        {
        }

        public Binding(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.BindingCollection i_BindingCollection, string i_ID, string i_Name, bool i_CreateDefaultTitleDescription, string i_By)
            : this(i_BindingCollection, i_ID, i_Name, System.String.Empty, System.String.Empty, i_CreateDefaultTitleDescription, i_By)
        {
        }

        public Binding(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.BindingCollection i_BindingCollection, string i_ID, string i_Name, string i_Title, string i_Description, bool i_CreateDefaultTitleDescription)
            : this(i_BindingCollection, i_ID, i_Name, System.String.Empty, System.String.Empty, i_CreateDefaultTitleDescription, System.String.Empty)
        {
        }

        public Binding(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.BindingCollection i_BindingCollection, string i_ID, string i_Name, string i_Title, string i_Description, bool i_CreateDefaultTitleDescription, string i_By)
        {
            m_XmlNamespaceManager = i_BindingCollection.RSSFeed.XmlNamespaceManager;
            m_NamespacePrefix = Microsoft.CSA.FeedSync.FeedSyncLibrary.XmlNamespaceManagerHelper.InitializeXmlNamespaceManager
                (
                i_BindingCollection.RSSFeed.XmlDocument,
                m_XmlNamespaceManager,
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.SIMPLE_FEED_BINDINGS_XML_NAMESPACE_PREFIX,
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.SIMPLE_FEED_BINDINGS_XML_NAMESPACE_URI
                );

            m_FeedSyncNamespacePrefix = Microsoft.CSA.FeedSync.FeedSyncLibrary.XmlNamespaceManagerHelper.InitializeXmlNamespaceManager
                (
                i_BindingCollection.RSSFeed.XmlDocument,
                m_XmlNamespaceManager,
                Microsoft.CSA.FeedSync.FeedSyncLibrary.Constants.FEEDSYNC_XML_NAMESPACE_PREFIX,
                Microsoft.CSA.FeedSync.FeedSyncLibrary.Constants.FEEDSYNC_XML_NAMESPACE_URI
                );

            m_XmlElement = this.CreateIdentifierXmlElement
                (
                i_BindingCollection,
                false
                );

            this.BindingInitialize
                (
                i_ID,
                i_Name,
                i_Title,
                i_Description,
                i_CreateDefaultTitleDescription
                );

            m_XmlElement = this.CreateIdentifierXmlElement
                (
                i_BindingCollection,
                false
                );

            m_XmlElement.SetAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.NAME_ATTRIBUTE, m_Name);

            if (!System.String.IsNullOrEmpty(m_Title))
                m_XmlElement.SetAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.TITLE_ATTRIBUTE, m_Title);

            if (!System.String.IsNullOrEmpty(m_Description))
                m_XmlElement.SetAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.DESCRIPTION_ATTRIBUTE, m_Description);

            m_Sync = new Microsoft.CSA.FeedSync.FeedSyncLibrary.Sync
                (
                i_BindingCollection.RSSFeed.XmlDocument,
                m_XmlNamespaceManager,
                i_By,
                System.Guid.NewGuid().ToString()
                );

            if (m_XmlElement.ChildNodes.Count > 0)
                m_XmlElement.InsertBefore(m_Sync.XmlElement, m_XmlElement.ChildNodes[0]);
            else
                m_XmlElement.AppendChild(m_Sync.XmlElement);
        }

        public Binding(System.Xml.XmlElement i_BindingXmlElement, System.Xml.XmlNamespaceManager i_XmlNamespaceManager, bool i_CreateDefaultTitleDescription)
        {
            if (i_BindingXmlElement == null)
                throw new System.ArgumentException("i_BindingXmlElement must be non-null!");

            bool InvalidElement =
                (i_BindingXmlElement.LocalName != Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.BINDING_ELEMENT_NAME) ||
                (i_BindingXmlElement.NamespaceURI != Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.SIMPLE_FEED_BINDINGS_XML_NAMESPACE_URI);

            if (InvalidElement)
                throw new System.ArgumentException("Invalid i_BindingXmlElement!");

            m_XmlElement = i_BindingXmlElement;
            m_XmlNamespaceManager = i_XmlNamespaceManager;
            m_NamespacePrefix = Microsoft.CSA.FeedSync.FeedSyncLibrary.XmlNamespaceManagerHelper.InitializeXmlNamespaceManager
                (
                m_XmlElement.OwnerDocument,
                m_XmlNamespaceManager,
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.SIMPLE_FEED_BINDINGS_XML_NAMESPACE_PREFIX,
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.SIMPLE_FEED_BINDINGS_XML_NAMESPACE_URI
                );

            m_FeedSyncNamespacePrefix = Microsoft.CSA.FeedSync.FeedSyncLibrary.XmlNamespaceManagerHelper.InitializeXmlNamespaceManager
                (
                m_XmlElement.OwnerDocument,
                m_XmlNamespaceManager,
                Microsoft.CSA.FeedSync.FeedSyncLibrary.Constants.FEEDSYNC_XML_NAMESPACE_PREFIX,
                Microsoft.CSA.FeedSync.FeedSyncLibrary.Constants.FEEDSYNC_XML_NAMESPACE_URI
                );

            System.Xml.XmlElement FeedSyncElement = (System.Xml.XmlElement)i_BindingXmlElement.SelectSingleNode
                (
                m_FeedSyncNamespacePrefix + ":" + Microsoft.CSA.FeedSync.FeedSyncLibrary.Constants.SYNC_ELEMENT_NAME,
                m_XmlNamespaceManager
                );

            if (FeedSyncElement == null)
                throw new System.ArgumentException("No FeedSync data found for item!");

            m_Sync = new Microsoft.CSA.FeedSync.FeedSyncLibrary.Sync
                (
                this,
                FeedSyncElement
                );

            string ID = m_XmlElement.GetAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.ID_ATTRIBUTE);
            string Name = m_XmlElement.GetAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.NAME_ATTRIBUTE);

            string Title = System.String.Empty;
            if (m_XmlElement.HasAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.TITLE_ATTRIBUTE))
                Title = m_XmlElement.GetAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.TITLE_ATTRIBUTE);

            string Description = System.String.Empty;
            if (m_XmlElement.HasAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.DESCRIPTION_ATTRIBUTE))
                Description = m_XmlElement.GetAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.DESCRIPTION_ATTRIBUTE);

            this.BindingInitialize
                (
                ID,
                Name,
                Title,
                Description,
                i_CreateDefaultTitleDescription
                );

            System.Xml.XmlNodeList NamespaceXmlNodeList = i_BindingXmlElement.SelectNodes
                (
                m_NamespacePrefix + ":" + Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.NAMESPACE_ELEMENT_NAME,
                m_XmlNamespaceManager
                );

            foreach (System.Xml.XmlElement NamespaceXmlElement in NamespaceXmlNodeList)
            {
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace Namespace = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace(NamespaceXmlElement);

                this.AddNamespace(Namespace, false);
                Microsoft.CSA.FeedSync.FeedSyncLibrary.XmlNamespaceManagerHelper.InitializeXmlNamespaceManager
                    (
                    m_XmlElement.OwnerDocument,
                    m_XmlNamespaceManager,
                    Namespace.LocalPrefix,
                    Namespace.URI
                    );
            }

            //  ------------------------------------------------------------------------------
            //  BIG HONKING NOTE: Must process PickLists before Fields for validation purposes

            System.Xml.XmlNodeList PickListXmlNodeList = i_BindingXmlElement.SelectNodes
                (
                m_NamespacePrefix + ":" + Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.PICKLIST_ELEMENT_NAME,
                m_XmlNamespaceManager
                );

            foreach (System.Xml.XmlElement PickListXmlElement in PickListXmlNodeList)
            {
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList PickList = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList
                    (
                    this,
                    PickListXmlElement
                    );

                this.AddPickList(PickList, false);
            }

            //  ------------------------------------------------------------------------------

            System.Xml.XmlNodeList FieldXmlNodeList = i_BindingXmlElement.SelectNodes
                (
                m_NamespacePrefix + ":" + Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.FIELD_ELEMENT_NAME,
                m_XmlNamespaceManager
                );

            foreach (System.Xml.XmlElement FieldXmlElement in FieldXmlNodeList)
            {
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field Field = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field
                    (
                    this,
                    FieldXmlElement
                    );

                this.AddField(Field, false);
            }
        }

        internal void BindingInitialize(string i_ID, string i_Name, string i_Title, string i_Description, bool i_CreateDefaultTitleDescription)
        {
            m_ID = i_ID;
            m_Name = i_Name;
            m_Title = i_Title;
            m_Description = i_Description;
            m_DefaultTitleDescription = i_CreateDefaultTitleDescription;

            if (i_CreateDefaultTitleDescription)
            {
                if (System.String.IsNullOrEmpty(m_Title))
                {
                    Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field Field = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field
                        (
                        this,
                        Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.DEFAULT_TITLE_ELEMENT_NAME,
                        Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.DEFAULT_TITLE_ELEMENT_NAME,
                        true,
                        Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field.ContentTypes.text
                        );

                    m_FieldList.Add(Field);
                    m_RequiredFieldSortedList.Add(Field.Element, Field);
                }

                if (System.String.IsNullOrEmpty(m_Description))
                {
                    Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field Field = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field
                        (
                        this,
                        Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.DEFAULT_DESCRIPTION_ELEMENT_NAME,
                        Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.DEFAULT_DESCRIPTION_ELEMENT_NAME,
                        false,
                        Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field.ContentTypes.html
                        );

                    m_FieldList.Add(Field);
                }
            }
        }

        public Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.BindingCollection BindingCollection
        {
            get
            {
                return m_BindingCollection;
            }

            internal set
            {
                if (value == null)
                    throw new System.ArgumentException("Value must be non-null!");

                m_BindingCollection = value;
            }
        }

        public string ID
        {
            get
            {
                return m_ID;
            }
        }

        public string Name
        {
            get
            {
                return m_Name;
            }
            set
            {
                if (System.String.IsNullOrEmpty(value))
                    throw new System.ArgumentException("value must be non-null!");

                m_Name = value;
                m_XmlElement.SetAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.NAME_ATTRIBUTE, m_Name);
            }
        }

        public string Title
        {
            get
            {
                return m_Title;
            }
            set
            {
                m_Title = value;
                m_XmlElement.SetAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.TITLE_ATTRIBUTE, m_Title);
            }
        }

        public string Description
        {
            get
            {
                return m_Description;
            }
            set
            {
                m_Description = value;
                m_XmlElement.SetAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.DESCRIPTION_ATTRIBUTE, m_Description);
            }
        }

        public bool DefaultTitleDescription
        {
            get
            {
                return m_DefaultTitleDescription;
            }
        }

        public string NamespacePrefix
        {
            get
            {
                return m_NamespacePrefix;
            }
        }

        public bool HasField(string i_Element)
        {
            Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field Field = null;
            return this.FindField(i_Element, out Field);
        }

        public bool FindField(string i_Element, out Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field o_Field)
        {
            o_Field = null;

            foreach (Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field Field in m_FieldList)
            {
                if (Field.Element == i_Element)
                {
                    o_Field = Field;
                    return true;
                }
            }

            return false;
        }

        public Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field GetField(string i_Element)
        {
            Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field Field = null;

            if (!this.FindField(i_Element, out Field))
                throw new System.ArgumentException("Invalid id: " + i_Element);

            return Field;
        }

        public System.Collections.Generic.IList<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field> Fields
        {
            get
            {
                return m_FieldList;
            }
        }

        public System.Collections.Generic.IList<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field> RequiredFields
        {
            get
            {
                return m_RequiredFieldSortedList.Values;
            }
        }

        public bool HasPickList(string i_ID)
        {
            return m_PickListSortedList.ContainsKey(i_ID);
        }

        public bool FindPickList(string i_ID, out Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList o_PickList)
        {
            o_PickList = null;

            if (!this.HasPickList(i_ID))
                return false;

            o_PickList = m_PickListSortedList[i_ID];

            return true;
        }

        public Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList GetPickList(string i_ID)
        {
            Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList PickList = null;

            if (!this.FindPickList(i_ID, out PickList))
                throw new System.ArgumentException("Invalid id: " + i_ID);

            return PickList;
        }

        public System.Collections.Generic.IList<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList> PickLists
        {
            get
            {
                return m_PickListSortedList.Values;
            }
        }

        public bool HasNamespace(string i_LocalPrefix)
        {
            return m_NamespaceSortedList.ContainsKey(i_LocalPrefix);
        }

        public bool FindNamespace(string i_LocalPrefix, out Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace o_Namespace)
        {
            o_Namespace = null;

            if (!this.HasNamespace(i_LocalPrefix))
                return false;

            o_Namespace = m_NamespaceSortedList[i_LocalPrefix];

            return true;
        }

        public Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace GetNamespace(string i_LocalPrefix)
        {
            Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace Namespace = null;

            if (!this.FindNamespace(i_LocalPrefix, out Namespace))
                throw new System.ArgumentException("Invalid prefix: " + i_LocalPrefix);

            return Namespace;
        }

        public System.Collections.Generic.IList<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace> Namespaces
        {
            get
            {
                return m_NamespaceSortedList.Values;
            }
        }

        public void AddField(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field i_Field)
        {
            this.AddField
                (
                i_Field,
                true
                );
        }

        internal void AddField(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field i_Field, bool i_AppendXmlElement)
        {
            if (i_Field == null)
                throw new System.ArgumentException("i_Field must be non-null!");

            if (this.HasField(i_Field.Element))
                throw new System.ArgumentException("Element already exists in Binding!");

            if (!System.String.IsNullOrEmpty(i_Field.PickListID) && (!this.HasPickList(i_Field.PickListID)))
                throw new System.ArgumentException("PickList with id '" + i_Field.PickListID + "' not found!");

            if (!System.String.IsNullOrEmpty(i_Field.PickListID) && (!System.String.IsNullOrEmpty(i_Field.DefaultValue)))
            {
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList PickList = this.GetPickList(i_Field.PickListID);

                bool ValidDefaultValue = false;
                foreach (Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickListItem PickListItem in PickList.PickListItems)
                {
                    if (PickListItem.Value == i_Field.DefaultValue)
                    {
                        ValidDefaultValue = true;
                        break;
                    }
                }

                if (!ValidDefaultValue)
                    throw new System.ArgumentException("Default value of '" + i_Field.DefaultValue + "' not valid for PickList with id '" + i_Field.PickListID + "'");
            }

            if (i_Field.XmlElement.OwnerDocument != m_XmlElement.OwnerDocument)
            {
                System.Xml.XmlElement ImportedFieldXmlElement = (System.Xml.XmlElement)m_XmlElement.OwnerDocument.ImportNode
                    (
                    i_Field.XmlElement,
                    true
                    );

                i_Field = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field
                    (
                    this,
                    ImportedFieldXmlElement
                    );
            }

            m_FieldList.Add(i_Field);

            if (i_Field.Required)
                m_RequiredFieldSortedList.Add(i_Field.Element, i_Field);

            if (i_AppendXmlElement)
                m_XmlElement.AppendChild(i_Field.XmlElement);

            i_Field.Binding = this;
        }

        public void RemoveField(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field i_Field)
        {
            if (i_Field == null)
                throw new System.ArgumentException("i_Field must be non-null!");

            if (!this.HasField(i_Field.Element))
                throw new System.ArgumentException("i_Field is not associated with Binding!");

            i_Field.XmlElement.ParentNode.RemoveChild(i_Field.XmlElement);
            m_FieldList.Remove(i_Field);
            m_RequiredFieldSortedList.Remove(i_Field.Element);
        }

        public void RemoveAllFields()
        {
            for (int Index = m_FieldList.Count - 1; Index >= 0; --Index)
            {
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field Field = m_FieldList[Index];
                this.RemoveField(Field);
            }
        }

        public void AddPickList(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList i_PickList)
        {
            this.AddPickList
                (
                i_PickList,
                true
                );
        }

        internal void AddPickList(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList i_PickList, bool i_AppendXmlElement)
        {
            if (i_PickList == null)
                throw new System.ArgumentException("i_PickList must be non-null!");

            if (this.HasPickList(i_PickList.ID))
                throw new System.ArgumentException("PickList already exists in Binding!");

            if (i_PickList.XmlElement.OwnerDocument != m_XmlElement.OwnerDocument)
            {
                System.Xml.XmlElement ImportedPickListXmlElement = (System.Xml.XmlElement)m_XmlElement.OwnerDocument.ImportNode
                    (
                    i_PickList.XmlElement,
                    true
                    );

                i_PickList = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList
                    (
                    this,
                    ImportedPickListXmlElement
                    );
            }

            m_PickListSortedList.Add(i_PickList.ID, i_PickList);

            if (i_AppendXmlElement)
                m_XmlElement.AppendChild(i_PickList.XmlElement);

            i_PickList.Binding = this;
        }

        public void RemovePickList(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList i_PickList)
        {
            if (i_PickList == null)
                throw new System.ArgumentException("i_PickList must be non-null!");

            if (!m_PickListSortedList.ContainsKey(i_PickList.ID))
                throw new System.ArgumentException("i_PickList is not associated with Binding!");

            i_PickList.XmlElement.ParentNode.RemoveChild(i_PickList.XmlElement);
            m_PickListSortedList.Remove(i_PickList.ID);
        }

        public void RemoveAllPickLists()
        {
            for (int Index = m_PickListSortedList.Values.Count - 1; Index >= 0; --Index)
            {
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.PickList PickList = m_PickListSortedList.Values[Index];
                this.RemovePickList(PickList);
            }
        }

        public void AddNamespace(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace i_Namespace)
        {
            this.AddNamespace
                (
                i_Namespace,
                true
                );
        }

        internal void AddNamespace(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace i_Namespace, bool i_AppendXmlElement)
        {
            if (i_Namespace == null)
                throw new System.ArgumentException("i_Namespace must be non-null!");

            if (this.HasNamespace(i_Namespace.LocalPrefix))
                throw new System.ArgumentException("Namespace already exists in Binding!");

            if (i_Namespace.XmlElement.OwnerDocument != m_XmlElement.OwnerDocument)
            {
                System.Xml.XmlElement ImportedNamespaceXmlElement = (System.Xml.XmlElement)m_XmlElement.OwnerDocument.ImportNode
                    (
                    i_Namespace.XmlElement,
                    true
                    );

                i_Namespace = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace(ImportedNamespaceXmlElement);
            }

            m_NamespaceSortedList.Add(i_Namespace.LocalPrefix, i_Namespace);

            if (i_AppendXmlElement)
                m_XmlElement.AppendChild(i_Namespace.XmlElement);

            i_Namespace.Binding = this;
        }

        public void RemoveNamespace(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace i_Namespace)
        {
            if (i_Namespace == null)
                throw new System.ArgumentException("i_Namespace must be non-null!");

            if (!m_NamespaceSortedList.ContainsKey(i_Namespace.LocalPrefix))
                throw new System.ArgumentException("i_Namespace is not associated with Binding!");

            i_Namespace.XmlElement.ParentNode.RemoveChild(i_Namespace.XmlElement);
            m_NamespaceSortedList.Remove(i_Namespace.LocalPrefix);
        }

        public void RemoveAllNamespaces()
        {
            for (int Index = m_NamespaceSortedList.Values.Count - 1; Index >= 0; --Index)
            {
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace Namespace = m_NamespaceSortedList.Values[Index];
                this.RemoveNamespace(Namespace);
            }
        }

        public bool CheckXmlElementForIdentifier(System.Xml.XmlElement i_XmlElement)
        {
            System.Xml.XmlNamespaceManager XmlNamespaceManager = new System.Xml.XmlNamespaceManager(i_XmlElement.OwnerDocument.NameTable);
            string NamespacePrefix = Microsoft.CSA.FeedSync.FeedSyncLibrary.XmlNamespaceManagerHelper.InitializeXmlNamespaceManager
                (
                i_XmlElement.OwnerDocument,
                XmlNamespaceManager,
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.SIMPLE_FEED_BINDINGS_XML_NAMESPACE_PREFIX,
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.SIMPLE_FEED_BINDINGS_XML_NAMESPACE_URI
                );

            string ElementName = Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.REFERENCE_ELEMENT_NAME;

            if (!System.String.IsNullOrEmpty(NamespacePrefix))
                ElementName = NamespacePrefix + ":" + ElementName;

            System.Xml.XmlNode ExistingReferenceXmlNode = i_XmlElement.SelectSingleNode
                (
                ElementName,
                XmlNamespaceManager
                );

            return (ExistingReferenceXmlNode != null);
        }

        public System.Xml.XmlElement CreateIdentifierXmlElement(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.BindingCollection i_BindingCollection)
        {
            return this.CreateIdentifierXmlElement
                (
                i_BindingCollection,
                true
                );
        }

        public System.Xml.XmlElement CreateIdentifierXmlElement(System.Xml.XmlElement i_ParentXmlElement)
        {
            System.Xml.XmlNamespaceManager XmlNamespaceManager = new System.Xml.XmlNamespaceManager(i_ParentXmlElement.OwnerDocument.NameTable);
            string NamespacePrefix = Microsoft.CSA.FeedSync.FeedSyncLibrary.XmlNamespaceManagerHelper.InitializeXmlNamespaceManager
                (
                i_ParentXmlElement.OwnerDocument,
                XmlNamespaceManager,
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.SIMPLE_FEED_BINDINGS_XML_NAMESPACE_PREFIX,
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.SIMPLE_FEED_BINDINGS_XML_NAMESPACE_URI
                );

            string ElementName = Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.REFERENCE_ELEMENT_NAME;

            if (!System.String.IsNullOrEmpty(NamespacePrefix))
                ElementName = NamespacePrefix + ":" + ElementName;

            System.Xml.XmlElement BindingReferenceXmlElement = i_ParentXmlElement.OwnerDocument.CreateElement
              (
              ElementName,
              Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.SIMPLE_FEED_BINDINGS_XML_NAMESPACE_URI
              );

            BindingReferenceXmlElement.SetAttribute
                (
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.ID_ATTRIBUTE,
                m_ID
                );

            return BindingReferenceXmlElement;
        }

        private System.Xml.XmlElement CreateIdentifierXmlElement(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.BindingCollection i_BindingCollection, bool i_IsReference)
        {
            string ElementName = "";

            if (i_IsReference)
                ElementName = Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.REFERENCE_ELEMENT_NAME;
            else
                ElementName = Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.BINDING_ELEMENT_NAME;

            if (!System.String.IsNullOrEmpty(i_BindingCollection.NamespacePrefix))
                ElementName = i_BindingCollection.NamespacePrefix + ":" + ElementName;

            System.Xml.XmlElement BindingReferenceXmlElement = i_BindingCollection.RSSFeed.XmlDocument.CreateElement
                (
                ElementName,
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.SIMPLE_FEED_BINDINGS_XML_NAMESPACE_URI
                );

            BindingReferenceXmlElement.SetAttribute(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Constants.ID_ATTRIBUTE, m_ID);

            return BindingReferenceXmlElement;
        }

        public System.Collections.Generic.Dictionary<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.FieldValue> GetFieldValuesFromXmlElement(System.Xml.XmlElement i_ItemXmlElement, bool i_IncludeHidden)
        {
            System.Collections.Generic.Dictionary<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.FieldValue> FieldValuesSortedList = new System.Collections.Generic.Dictionary<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.FieldValue>();

            foreach (Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field Field in m_FieldList)
            {
                //  Don't return hidden field names/values
                if (Field.Hidden && !i_IncludeHidden)
                    continue;

                string Text = System.String.Empty;

                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.FieldValue FieldValue = null;

                System.Xml.XmlNodeList FieldXmlNodeList = i_ItemXmlElement.SelectNodes(Field.Element, XmlNamespaceManager);

                if (Field.Array)
                {
                    string[] Values = new string[FieldXmlNodeList.Count];

                    for (int Index = 0; Index < Values.Length; ++Index)
                        Values[Index] = FieldXmlNodeList[Index].InnerText;

                    FieldValue = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.FieldValue(Field.Element, Values);
                }
                else
                {

                    if (FieldXmlNodeList.Count > 1)
                        throw new System.Exception("Non-array field with id '" + Field.Element + "' has multiple values!");

                    System.Xml.XmlElement FieldXmlElement = null;
                    if (FieldXmlNodeList.Count == 1)
                        FieldXmlElement = (System.Xml.XmlElement)FieldXmlNodeList[0];

                    bool HasText =
                        (FieldXmlElement != null) &&
                        (FieldXmlElement.ChildNodes.Count > 0) &&
                        (FieldXmlElement.ChildNodes[0] is System.Xml.XmlText);

                    if (HasText)
                    {
                        System.Xml.XmlText XmlText = (System.Xml.XmlText)FieldXmlElement.ChildNodes[0];
                        Text = XmlText.InnerText;
                    }

                    FieldValue = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.FieldValue(Field.Element, Text);
                }

                FieldValuesSortedList.Add(Field.Element, FieldValue);
            }

            return FieldValuesSortedList;
        }

        public void RemoveFieldValuesForXmlElement(System.Xml.XmlElement i_ItemXmlElement, System.Collections.Generic.Dictionary<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.FieldValue> i_FieldValueSortedList)
        {
            foreach (Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.FieldValue FieldValue in i_FieldValueSortedList.Values)
            {
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field Field = this.GetField(FieldValue.ID);

                System.Xml.XmlNodeList FieldXmlNodeList = i_ItemXmlElement.SelectNodes(Field.Element, XmlNamespaceManager);
                foreach (System.Xml.XmlNode FieldXmlNode in FieldXmlNodeList)
                    FieldXmlNode.ParentNode.RemoveChild(FieldXmlNode);
            }
        }

        public void SetFieldValuesForXmlElement(System.Xml.XmlElement i_ItemXmlElement, System.Collections.Generic.Dictionary<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.FieldValue> i_FieldValueSortedList)
        {
            this.RemoveFieldValuesForXmlElement
                (
                i_ItemXmlElement,
                i_FieldValueSortedList
                );

            foreach (Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.FieldValue FieldValue in i_FieldValueSortedList.Values)
            {
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Field Field = this.GetField(FieldValue.ID);

                string[] ElementNames = Field.Element.Split('/');
                string[] NamespacePrefixes = new string[ElementNames.Length];
                string[] NamespaceURIs = new string[ElementNames.Length];

                for (int Index = 0; Index < ElementNames.Length; ++Index)
                {
                    string ElementName = ElementNames[Index];
                    if (ElementName.IndexOf(":") != -1)
                    {
                        string NamespacePrefix = ElementName.Substring(0, ElementName.IndexOf(":"));
                        Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Namespace Namespace = this.GetNamespace(NamespacePrefix);

                        ElementName = ElementName.Substring(ElementName.IndexOf(":") + 1);
                        NamespacePrefixes[Index] = Namespace.MappedPrefix;
                        NamespaceURIs[Index] = Namespace.URI;
                    }

                    ElementNames[Index] = ElementName;
                }

                if (Field.Array)
                {
                    foreach (string Value in FieldValue.Values)
                    {
                        System.Xml.XmlElement FieldValueXmlElement = Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.MiscHelpers.CreateElementHierarchy
                            (
                            i_ItemXmlElement.OwnerDocument,
                            i_ItemXmlElement,
                            ElementNames,
                            NamespaceURIs,
                            NamespacePrefixes,
                            m_XmlNamespaceManager,
                            true
                            );

                        FieldValueXmlElement.InnerText = Value;
                    }
                }
                else
                {
                    System.Xml.XmlElement FieldValueXmlElement = Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.MiscHelpers.CreateElementHierarchy
                        (
                        i_ItemXmlElement.OwnerDocument,
                        i_ItemXmlElement,
                        ElementNames,
                        NamespaceURIs,
                        NamespacePrefixes,
                        m_XmlNamespaceManager
                        );

                    FieldValueXmlElement.InnerText = FieldValue.Value;
                }
            }
        }

        public string[] GetFieldIDsForTitle()
        {
            return Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.MiscHelpers.GetFieldIDsForExpression(m_Title);
        }

        public string[] GetFieldIDsForDescription()
        {
            return Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.MiscHelpers.GetFieldIDsForExpression(m_Description);
        }

        #region Microsoft.CSA.FeedSync.FeedSyncLibrary.IFeedSyncItem

        public System.Xml.XmlElement XmlElement
        {
            get
            {
                return m_XmlElement;
            }
        }

        public Microsoft.CSA.FeedSync.FeedSyncLibrary.Sync Sync
        {
            get
            {
                return m_Sync;
            }
            set
            {
                m_Sync = value;
            }
        }

        public System.Xml.XmlNamespaceManager XmlNamespaceManager
        {
            get
            {
                return m_XmlNamespaceManager;
            }
        }

        public void Update(System.DateTime? i_WhenDateTime, string i_By)
        {
            m_Sync.Update(i_WhenDateTime, i_By, true);
        }

        public void ResolveConflicts(System.DateTime? i_WhenDateTime, string i_By)
        {
            m_Sync.ResolveConflicts(i_WhenDateTime, i_By, true);
        }

        public void Delete(System.DateTime? i_WhenDateTime, string i_By)
        {
            m_Sync.Delete(i_WhenDateTime, i_By, true);
        }

        public Microsoft.CSA.FeedSync.FeedSyncLibrary.IFeedSyncItem Clone()
        {
            System.Xml.XmlElement ClonedXmlElement = (System.Xml.XmlElement)m_XmlElement.CloneNode(true);
            Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Binding Binding = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrary.Binding
                (
                ClonedXmlElement,
                m_XmlNamespaceManager,
                this.DefaultTitleDescription
                );

            return Binding;
        }

        public Microsoft.CSA.FeedSync.FeedSyncLibrary.Sync Initialize(System.Xml.XmlElement i_XmlElement, System.Xml.XmlNamespaceManager i_XmlNamespaceManager)
        {
            if (i_XmlElement == null)
                throw new System.ArgumentException("i_XmlElement must be non-null!");

            if (i_XmlNamespaceManager == null)
                throw new System.ArgumentException("i_XmlNamespaceManager  must be non-null!");

            bool Initialized =
                (m_XmlElement != null) ||
                (m_XmlNamespaceManager != null) ||
                (m_Sync != null);

            if (Initialized)
                throw new System.Exception("Already initialized!");

            m_XmlElement = i_XmlElement;
            m_XmlNamespaceManager = i_XmlNamespaceManager;

            m_Sync = new Microsoft.CSA.FeedSync.FeedSyncLibrary.Sync(this);

            return m_Sync;
        }

        #endregion

    }
}
